package com.example.fall_guard_band.service.ServiceImpl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.example.fall_guard_band.mapper.RoleMapper;
import com.example.fall_guard_band.mapper.UserRoleMapper;
import com.example.fall_guard_band.pojo.dto.RoleDTO;
import com.example.fall_guard_band.pojo.dto.CreateRoleRequest;
import com.example.fall_guard_band.pojo.dto.UpdateRoleRequest;
import com.example.fall_guard_band.pojo.entity.Role;
import com.example.fall_guard_band.pojo.entity.UserRole;
import com.example.fall_guard_band.service.RoleService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class RoleServiceImpl implements RoleService {

    private final RoleMapper roleMapper;
    private final UserRoleMapper userRoleMapper;

    @Override
    public List<RoleDTO> listRoles(Integer status) {
        LambdaQueryWrapper<Role> wrapper = new LambdaQueryWrapper<>();
        if (status != null) {
            wrapper.eq(Role::getStatus, status);
        }
        List<Role> roles = roleMapper.selectList(wrapper);
        List<RoleDTO> list = new ArrayList<>();
        for (Role r : roles) {
            list.add(toDTO(r));
        }
        return list;
    }

    @Override
    public List<RoleDTO> listUserRoles(Long userId) {
        if (userId == null) return List.of();
        List<UserRole> urs = userRoleMapper.selectList(new LambdaQueryWrapper<UserRole>().eq(UserRole::getUserId, userId));
        Set<Long> roleIds = urs.stream().map(UserRole::getRoleId).filter(Objects::nonNull).collect(Collectors.toSet());
        if (roleIds.isEmpty()) return List.of();
        List<Role> roles = roleMapper.selectList(new LambdaQueryWrapper<Role>().in(Role::getId, roleIds));
        List<RoleDTO> list = new ArrayList<>();
        for (Role r : roles) {
            list.add(toDTO(r));
        }
        return list;
    }

    @Override
    public boolean createRole(CreateRoleRequest req) {
        if (req == null || isBlank(req.getRoleName())) {
            return false;
        }
        Integer status = req.getStatus() == null ? 1 : req.getStatus();
        if (status != 0 && status != 1) {
            return false;
        }
        Role exists = roleMapper.selectOne(new LambdaQueryWrapper<Role>().eq(Role::getRoleName, req.getRoleName()));
        if (exists != null) {
            return false;
        }
        Role r = new Role();
        r.setRoleName(req.getRoleName());
        r.setDescription(req.getDescription());
        r.setStatus(status);
        java.time.LocalDateTime now = java.time.LocalDateTime.now();
        r.setCreatedAt(now);
        r.setUpdatedAt(now);
        return roleMapper.insert(r) == 1;
    }

    @Override
    public boolean updateRole(Long id, UpdateRoleRequest req) {
        if (id == null || req == null) {
            return false;
        }
        Role role = roleMapper.selectById(id);
        if (role == null) {
            return false;
        }
        if (req.getRoleName() != null && !isBlank(req.getRoleName())) {
            Role conflict = roleMapper.selectOne(new LambdaQueryWrapper<Role>()
                    .eq(Role::getRoleName, req.getRoleName())
                    .ne(Role::getId, id));
            if (conflict != null) {
                return false;
            }
            role.setRoleName(req.getRoleName());
        }
        if (req.getDescription() != null) {
            role.setDescription(req.getDescription());
        }
        if (req.getStatus() != null) {
            if (req.getStatus() != 0 && req.getStatus() != 1) {
                return false;
            }
            role.setStatus(req.getStatus());
        }
        role.setUpdatedAt(java.time.LocalDateTime.now());
        return roleMapper.updateById(role) == 1;
    }

    @Override
    public boolean deleteRole(Long id) {
        if (id == null) {
            return false;
        }
        Role role = roleMapper.selectById(id);
        if (role == null) {
            return false;
        }
        return roleMapper.deleteById(id) == 1;
    }

    private RoleDTO toDTO(Role r) {
        return RoleDTO.builder()
                .id(r.getId())
                .roleName(r.getRoleName())
                .description(r.getDescription())
                .status(r.getStatus())
                .build();
    }

    private boolean isBlank(String s) {
        return s == null || s.trim().isEmpty();
    }
}